<?php

/**
 *  Utility functions used in .istall and .module files
 */

define ('TEMPLATE_SITE_NAME',       'template');
define ('TEMPLATE_PRIVATE_PREFIX',  'template_private_');
define ('TEMPLATE_SHARED_PREFIX',   'main_');
define ('TEMPLATE_BID',             1);
define ('AGGREGATOR_BID',           0);

/**
 *  Read file content and return string with them
 */
function mutil_file_read_string($filename)
{
  $fh = fopen($filename, "r");
  if ($fh) {
    $result = fread($fh, filesize($filename));
    fclose($fh);
  }
  return $result; 
}

/**
 *  Write string in to file
 */
function mutil_file_write_string($filename, $str)
{
  $fh = fopen($filename, "w+");
  if ($fh) {
    fwrite($fh, $str);
    fclose($fh);
  }
}

/**
 * Creates directories recursive
 */
function mutil_mkdir_recursive($name) {
  if (($dirname = dirname($name)) != '.') {
    mutil_mkdir_recursive($dirname);
  }
  
  return @mkdir($name);
}


/**
 * Copy recursive all contents of $src to $dest
 */
function mutil_copy_dir_recursive($src, $dest){
    
  if (is_dir($dest)) {
    $dest .= '/' . basename($src);
  }
  
  if (!mutil_mkdir_recursive($dest)) {
    return FALSE;
  }
  else{
    //Preserve permissions
    chmod($dest, fileperms($src));
  }
  
  if ($handle = opendir($src)) {
    //This is the correct way to loop over the directory.
    while (false !== ($file = readdir($handle))) {
      if (!($file == '.' || $file == '..')) {
        $nextsrc  = "$src/$file";
        $nextdest = "$dest/$file";
        if (is_dir($nextsrc)) {
          if (!mutil_copy_dir_recursive($nextsrc, $nextdest)) {
            return FALSE;          
          }
        }
        else {
          if (!copy($nextsrc, $nextdest)) {
            return FALSE;
          }
          else {
            //Preserve permissions
            chmod($nextdest, fileperms($nextsrc));
          }
        }
      }
    }
    closedir($handle);
  }
  
  return TRUE;
}

function mutil_second_level_domain($url) {
  // get host name from URL
  preg_match("@^(http:\/\/)?([^\/]+)@i", $url, $matches);
  $host = $matches[2];

  // get last two segments of host name
  preg_match("@[^\.\/]+\.[^\.\/]+$@", $host, $matches);
  
  return $matches[0];
}

function mutil_template_base() {
  return TEMPLATE_SITE_NAME . '.' . mutil_aggregator_base();
}

/**
 * Return base for aggregator site
 * for now this is second-levele-domain.tld  
 */
function mutil_aggregator_base() {
  global $base_url;
  return mutil_second_level_domain($base_url);
//  global $cookie_domain;
//  return $cookie_domain;
}

/**
 *  Extract base part from $base_url
 */
function mutil_current_base()
{
  global $base_url;
    
  // strip out 'http://'
  preg_match("@^(http:\/\/)?(.*)@i", $base_url, $matches);
  $base = $matches[2];

  return $base;
}

/** 
 *  Create drupal site dir name by site base
 */
function mutil_site_base_to_dirname($site_base)
{
  if ($site_base == mutil_aggregator_base()) {
    return 'sites/default';
  }
  else {
    return 'sites/' . implode('.', split('[./\]', $site_base));
  }
}

/**
 * Create human readable string from size in bytes
 */
function mutil_format_size($size) {
  if ($size > 1024 * 1024) {
    $result = preg_replace('@^(.*\..{2}).*$@', '\1', ($size / (1024 * 1024))) . 'M';
  }
  else if ($size > 1024) {
    $result = preg_replace('@^(.*\..{2}).*$@', '\1', ($size / 1024)) . 'K';
  }
  else if ($size > 0) {
    $result = $size . 'B'; 
  }
  else {
    $result = $size;
  }
  
  return $result;
}

/**
 * Return directory size 
 */
function mutil_dirsize_recursive($dirname)
{
  $result = 0;
  
  if ($handle = opendir($dirname)) {
    //This is the correct way to loop over the directory.
    while (FALSE !== ($file = readdir($handle))) {
      if (!($file == '.' || $file == '..')) {
        $nextfile = "$dirname/$file";
        if (is_dir($nextfile)){
          $result += mutil_dirsize_recursive($nextfile);
        }
        else {
          $result += filesize($nextfile);
        }
      }
    }
    closedir($handle);
  }
  
  return $result;
}


/**
 *  Remove directory and all contents
 */
function mutil_rmdir_recursive($dirname)
{
  if ($handle = opendir($dirname)) {
    //This is the correct way to loop over the directory.
    while (false !== ($file = readdir($handle))) {
      if (!($file == '.' || $file == '..')) {
        $nextfile = "$dirname/$file";
        if (is_dir($nextfile)){
          if (!mutil_rmdir_recursive($nextfile)){
            return FALSE;          
          }
        }
        else {
          if (!unlink($nextfile)){
            return FALSE;
          }
        }
      }
    }
    closedir($handle);
  }
  
  if (!rmdir($dirname)){
    return FALSE;
  } 
  
  return TRUE;
}

/**
 * Replace first occurence
 *  //{tag}
 *  ... old value .. 
 *  //{/tag}
 * 
 * In to 
 *  //{tag}
 *  ... value .. 
 *  //{/tag}
 *
 * and return replacement result
 */
function mutil_set_tag($tag, $value, $subject)
{
  return preg_replace(
    "@(//{{$tag}})(.*)(//{/{$tag}})@s", 
    "\\1\n$value\n\\3",
    $subject);
}

/**
 * Read tag from file
 */
function mutil_get_tag($tag, $subject) 
{
  return mutil_preg_get("@(.*//{{$tag}})(.*)(.*//{/{$tag}})@s", $subject, 2);
}

/**
 * Get match with $match_no from $preg
 */
function mutil_preg_get($preg, $subject, $match_no) {
  $matches = array();
  preg_match($preg, $subject, $matches);
  return $matches[$match_no];
}

/**
 *  Do batch drop tables job
 */
function mutil_drop_tables($prefix, $exclude = NULL) {
  if ($exclude == NULL) {
    $exclude = array();
  }  

  //Only mysql version for now
  $result = db_query("SHOW TABLES");
  
  while($tables = db_fetch_object($result)) {
    foreach ($tables as $db => $src_table) {
      if (preg_match("/^$prefix(.*)$/", $src_table, $matches)) {
        if (array_search($src_table, $exclude) === FALSE) {
          db_query("DROP TABLE %s", $src_table);
        }
      }
    }
  }
}

/**
 *  Return summary size of all tables with given prefix.
 *  Summ of data and index files sizes is used.
 */
function mutil_tables_size($prefix) {
  $result = db_query("SHOW TABLE STATUS LIKE '%s%'", $prefix);
  while ($table = db_fetch_object($result)) {
    $size += $table->Data_length + $table->Index_length;
  }
  
  return $size;
}

/**
 * For all tables which names starts from $src_prefix 
 * create dulicate with $dst_prefix.
 * $exclude - array of table names which duplication should be ommited
 */
function mutil_duplicate_tables ($src_prefix, $dst_prefix, $exclude = NULL) {
  if ($exclude == NULL) {
    $exclude = array();
  }  
  
  //Only mysql version for now
  $result = db_query("SHOW TABLES");
  
  while($tables = db_fetch_object($result)) {
    foreach ($tables as $db => $src_table) {
      if (preg_match("/^$src_prefix(.*)$/", $src_table, $matches)) {
        $table_basename = $matches[1];
        if (array_search($table_basename, $exclude) === FALSE) {
          mutil_duplicate_table($src_table, $dst_prefix . $table_basename);
        }
      }
    }
  }  
}

/**
 * Create $dst as copy of $src table 
 * If $dst already exists drop $dst before operation
 */
function mutil_duplicate_table($src, $dst) 
{
  $result = db_fetch_array(db_query("SHOW CREATE TABLE %s", $src));
  $sql_create = $result['Create Table'];
  
  if (!empty($sql_create)) {
    $sql_create = preg_replace("@(CREATE\s+TABLE[^(]+)($src)([^(]+\()@", "\\1$dst\\3", $sql_create);
    
    db_query("DROP TABLE IF EXISTS %s", $dst);  
    db_query($sql_create);
    db_query("INSERT INTO %s SELECT * FROM %s", $dst, $src);
  }
}

/**
 *  Dump form, using drupal_set_message.
 */
function mutil_dump_form($form, $prefix = '') {
  
  if (empty($prefix)){
    drupal_set_message('/***** jju_dump_form *****/');
  }
  
  foreach($form as $key => $element){
    if (is_array($element)) {
      drupal_set_message("$prefix $key [array]");
      mutil_dump_form($element, "-$prefix");
    }
    elseif (is_object($element)) {
      drupal_set_message("$prefix $key [object]");
      mutil_dump_form((array)$element, "-$prefix");
    }
    else{
      drupal_set_message("$prefix $key (" . check_plain($element) . ")");
    }
  }
}

/**
 *  Create new or update exisitng record in multiste table
 *  $base     - site selector
 *  $created  - new site creation time
 *  $new_bid  - new bid for the site
 */ 
function mutil_update_site_mark($base, $created = NULL, $new_bid = NULL) {
  if ($created == NULL) {
    $created = time();
  }
  
  $count = db_result(db_query("SELECT COUNT(*) FROM {multisite} WHERE base = '%s'", $base));
  if ($count) {
    $old_bid = db_result(db_query("SELECT bid FROM {multisite} WHERE base = '%s'", $base));
    if (!isset($new_bid)) {
      $new_bid = $old_bid;
    }
    db_query("UPDATE {multisite} SET bid = %d, created = %d WHERE bid = %d", $new_bid, $old_bid);
  }
  else {
    db_query("INSERT INTO {multisite} (base, created) VALUES ('%s', %d)", $base, $created);

    if (isset($new_bid)) {
      $old_bid = db_last_insert_id('multisite', 'bid');
      db_query("UPDATE {multisite} SET bid = %d WHERE bid = %d", $new_bid, $old_bid);
    }
  }
}

/**
 *  Remove site record from multisite table
 *  $base - site selector
 */ 
function mutil_remove_site_mark($bid) {
  db_query("DELETE FROM {multisite} WHERE bid = %d", $bid);  
}

/**
 *  Return private prefix for $base tables
 */
function mutil_create_private_prefix($base) {
  if ($base == mutil_aggregator_base()) {
    return TEMPLATE_SHARED_PREFIX;
  }
  elseif ($base == mutil_template_base()) {
    return TEMPLATE_PRIVATE_PREFIX;
  }
  else {
    return 'z_' . strtr($base, ".-", "__") . "_";
  }
}

/**
 *  Return $db_prefix variable value from settings.php file
 *  which corresponds $base
 */
function muitil_db_prefix($base) {
  $settings_php = mutil_file_read_string(mutil_site_base_to_dirname($base) . '/settings.php');
  $settings_db_prefix = mutil_get_tag('db_prefix', $settings_php);
  $settings_db_prefix_value = eval($settings_db_prefix . ' return $db_prefix;');
  
  return $settings_db_prefix_value;
}


/**
 *  Make site specific directories and con fig files writable
 */
function mutil_make_site_writable($base){
  $site_dir = mutil_site_base_to_dirname($base);
  
  //Set permissions
  chmod($site_dir, 0777);
  chmod($site_dir . '/files', 0777);
  chmod($site_dir . '/modules', 0777);
  chmod($site_dir . '/themes', 0777);
  chmod($site_dir . '/settings.php', 0666);
}
